/**
 * Minio文件上传工具类
 * 基于已有的MinioUploader实现MCP接口
 */

import { promises as fs } from 'fs';
import { basename, extname } from 'path';
import type { ToolResult } from '../../core/tool-schema.js';
import { createChildLogger, createErrorLogContext } from '../../utils/logger.js';
import { minioUploader } from '../../minio/uploader.js';

export interface UploadFileParams {
  /** 本地文件路径 */
  filePath: string;
  /** 对象名称（可选） */
  objectName?: string;
  /** 存储桶名称（可选） */
  bucketName?: string;
  /** 目录前缀（可选） */
  directory?: string;
  /** 内容类型（可选） */
  contentType?: string;
  /** 链接过期时间（秒） */
  expirySeconds?: number;
}

export interface UploadMultipleFilesParams {
  /** 文件列表 */
  files: Array<{
    filePath: string;
    objectName?: string;
    contentType?: string;
  }>;
  /** 存储桶名称（可选） */
  bucketName?: string;
  /** 目录前缀（可选） */
  directory?: string;
  /** 链接过期时间（秒） */
  expirySeconds?: number;
}

export interface GenerateDownloadLinkParams {
  /** 对象路径 */
  objectPath: string;
  /** 存储桶名称（可选） */
  bucketName?: string;
  /** 链接过期时间（秒） */
  expirySeconds?: number;
}

export interface CheckStatusParams {
  // 无需参数
}

export class MinioUploadTool {
  private logger = createChildLogger('MinioUploadTool');

  /**
   * 上传单个文件到Minio
   */
  async uploadFile(params: UploadFileParams): Promise<ToolResult> {
    try {
      this.logger.info('Starting file upload to Minio', {
        filePath: params.filePath,
        objectName: params.objectName,
        directory: params.directory
      });

      // 检查Minio是否配置
      if (!minioUploader.isConfigured()) {
        return {
          success: false,
          error: 'Minio未配置，请检查环境变量：MINIO_ENDPOINT、MINIO_ACCESS_KEY、MINIO_SECRET_KEY'
        };
      }

      // 检查文件是否存在
      try {
        await fs.access(params.filePath);
      } catch (error) {
        return {
          success: false,
          error: `文件不存在：${params.filePath}`
        };
      }

      // 确定对象名称
      const objectName = params.objectName || basename(params.filePath);
      
      // 检测内容类型
      const contentType = params.contentType || this.detectContentType(params.filePath);

      // 构建完整的对象路径
      const directory = params.directory || 'files';
      const fullObjectName = `${directory}/${objectName}`;

      // 调用现有的上传功能
      const result = await minioUploader.uploadFile({
        filePath: params.filePath,
        objectName: fullObjectName
      });

      if (!result.success) {
        return {
          success: false,
          error: result.message
        };
      }

      const response = {
        success: true,
        data: {
          url: result.url,
          presignedUrl: result.presignedUrl,
          objectPath: result.objectPath,
          objectName: result.objectName,
          bucketName: process.env.MINIO_BUCKET,
          contentType,
          expirySeconds: params.expirySeconds || 3600,
          uploadedAt: new Date().toISOString()
        },
        message: `文件上传成功，下载链接有效期${Math.floor((params.expirySeconds || 3600) / 60)}分钟`
      };

      this.logger.info('File upload completed successfully', response.data);
      return response;

    } catch (error) {
      this.logger.error(
        'File upload failed',
        createErrorLogContext(error, { filePath: params.filePath })
      );
      return {
        success: false,
        error: error instanceof Error ? error.message : String(error)
      };
    }
  }

  /**
   * 批量上传多个文件
   */
  async uploadMultipleFiles(params: UploadMultipleFilesParams): Promise<ToolResult> {
    try {
      this.logger.info('Starting batch upload to Minio', {
        fileCount: params.files.length,
        directory: params.directory
      });

      // 检查Minio是否配置
      if (!minioUploader.isConfigured()) {
        return {
          success: false,
          error: 'Minio未配置，请检查环境变量'
        };
      }

      const results: any[] = [];
      const errors: string[] = [];

      // 依次上传每个文件
      for (const fileInfo of params.files) {
        try {
          const uploadResult = await this.uploadFile({
            filePath: fileInfo.filePath,
            objectName: fileInfo.objectName,
            contentType: fileInfo.contentType,
            directory: params.directory,
            bucketName: params.bucketName,
            expirySeconds: params.expirySeconds
          });

          if (uploadResult.success) {
            results.push(uploadResult.data);
          } else {
            errors.push(`${basename(fileInfo.filePath)}: ${uploadResult.error}`);
          }
        } catch (error) {
          const errorMsg = error instanceof Error ? error.message : String(error);
          errors.push(`${basename(fileInfo.filePath)}: ${errorMsg}`);
        }
      }

      const successCount = results.length;
      const failureCount = errors.length;

      return {
        success: successCount > 0,
        data: {
          uploads: results,
          successCount,
          failureCount,
          errors: errors.length > 0 ? errors : undefined
        },
        message: `批量上传完成：成功${successCount}个，失败${failureCount}个`
      };

    } catch (error) {
      this.logger.error(
        'Batch upload failed',
        createErrorLogContext(error, { fileCount: params.files.length })
      );
      return {
        success: false,
        error: error instanceof Error ? error.message : String(error)
      };
    }
  }

  /**
   * 生成下载链接
   */
  async generateDownloadLink(params: GenerateDownloadLinkParams): Promise<ToolResult> {
    try {
      this.logger.info('Generating download link', {
        objectPath: params.objectPath,
        expirySeconds: params.expirySeconds
      });

      // 检查Minio是否配置
      if (!minioUploader.isConfigured()) {
        return {
          success: false,
          error: 'Minio未配置，请检查环境变量'
        };
      }

      const bucketName = params.bucketName || process.env.MINIO_BUCKET;
      if (!bucketName) {
        return {
          success: false,
          error: '存储桶名称未指定，请设置MINIO_BUCKET环境变量或传入bucketName参数'
        };
      }

      // 使用MinioUploader的公开方法生成预签名URL
      const presignedUrl = await minioUploader.generatePublicPresignedUrl(
        bucketName,
        params.objectPath,
        params.expirySeconds || 3600
      );

      if (!presignedUrl) {
        return {
          success: false,
          error: '生成下载链接失败'
        };
      }

      return {
        success: true,
        data: {
          presignedUrl,
          objectPath: params.objectPath,
          bucketName,
          expirySeconds: params.expirySeconds || 3600,
          generatedAt: new Date().toISOString()
        },
        message: `下载链接生成成功，有效期${Math.floor((params.expirySeconds || 3600) / 60)}分钟`
      };

    } catch (error) {
      this.logger.error(
        'Generate download link failed',
        createErrorLogContext(error, { objectPath: params.objectPath })
      );
      return {
        success: false,
        error: error instanceof Error ? error.message : String(error)
      };
    }
  }

  /**
   * 检查Minio状态
   */
  async checkStatus(params: CheckStatusParams): Promise<ToolResult> {
    try {
      const isConfigured = minioUploader.isConfigured();
      const requiredEnvVars = [
        'MINIO_ENDPOINT',
        'MINIO_ACCESS_KEY',
        'MINIO_SECRET_KEY',
        'MINIO_BUCKET'
      ];

      const envStatus = requiredEnvVars.reduce((acc, envVar) => {
        acc[envVar] = !!process.env[envVar];
        return acc;
      }, {} as Record<string, boolean>);

      const optionalEnvVars = {
        MINIO_PORT: process.env.MINIO_PORT || '9000',
        MINIO_USE_SSL: process.env.MINIO_USE_SSL || 'false'
      };

      return {
        success: true,
        data: {
          configured: isConfigured,
          environment: {
            required: envStatus,
            optional: optionalEnvVars
          },
          endpoint: process.env.MINIO_ENDPOINT ? 
            `${process.env.MINIO_USE_SSL === 'true' ? 'https' : 'http'}://${process.env.MINIO_ENDPOINT}:${process.env.MINIO_PORT || '9000'}` : 
            null,
          defaultBucket: process.env.MINIO_BUCKET,
          checkedAt: new Date().toISOString()
        },
        message: isConfigured ? 'Minio配置正常' : 'Minio配置不完整，请检查环境变量'
      };

    } catch (error) {
      this.logger.error('Check Minio status failed', createErrorLogContext(error));
      return {
        success: false,
        error: error instanceof Error ? error.message : String(error)
      };
    }
  }

  /**
   * 检测文件内容类型
   */
  private detectContentType(filePath: string): string {
    const ext = extname(filePath).toLowerCase();
    const mimeTypes: Record<string, string> = {
      '.pdf': 'application/pdf',
      '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
      '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      '.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
      '.zip': 'application/zip',
      '.json': 'application/json',
      '.txt': 'text/plain',
      '.md': 'text/markdown',
      '.html': 'text/html',
      '.css': 'text/css',
      '.js': 'application/javascript',
      '.ts': 'text/typescript',
      '.png': 'image/png',
      '.jpg': 'image/jpeg',
      '.jpeg': 'image/jpeg',
      '.gif': 'image/gif',
      '.svg': 'image/svg+xml'
    };

    return mimeTypes[ext] || 'application/octet-stream';
  }

}
